#ifndef WEBSERVER_H
#define WEBSERVER_H

#include <memory>
#include "../timer/heaptimer.h"
#include "epoller.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <functional>
#include <string.h>
#include <fcntl.h>
#include "../http/httpconn.h"
#include "../log/log.h"
#include "../pool/threadpool.h"
#include "../pool/sqlconnpool.h"

class WebServer {
public:

    WebServer
        (int port, int trigmode, int timeoutMS, bool optLinger, 
        int sqlport, const char* sqluser, const char* sqlpwd, 
        const char* dbName, int connPoolNum, int threadNum,
        bool openLog, int logLevel, int logQueSize);
    ~WebServer();
    void Start();
    void Tick(); //清除超时节点

private:
    bool InitSocket();
    void InitEventMode(int trigMode); // 初始化事件模式
    void DealListen(); // 监听套接字产生事件，添加新用户
    void AddClient(int fd, sockaddr_in addr); // 添加新用户
    void SendError(int fd, const char* info); // 给客户端发送错误信息
    void CloseConn(HttpConn *client);
    void DealRead(HttpConn *client);
    void DealWrite(HttpConn *client);
    void ExtentTime(HttpConn *client);

    void OnRead(HttpConn *client);
    void OnWrite(HttpConn *client);
    void OnProcess(HttpConn *client);


private:
    static const int MAX_FD = 65536; // 最大描述符数

    static int SetFdNonblock(int fd);

    int m_port; // 端口号
    uint32_t m_listenEvent; // 监听事件
    uint32_t m_connEvent; // 连接事件
    int m_timeout; // 服务器等待事件的超时时间
    int m_listenFd; // 监听的事件描述符    
    bool m_openLinger; // 是否优雅关闭    
    bool m_isClose; // 服务器是否关闭
    char* m_srcDir;

    std::unique_ptr<HeapTimer> m_timer; // 最小堆定时器，unique_ptr保证一个指针独自拥有空间所有权，不能拷贝复制、但是可以移动构造
    std::unique_ptr<ThreadPool> m_threadpool;    
    std::unique_ptr<Epoller> m_Epoller;
    std::unordered_map<int, HttpConn> m_users; // 键为文件描述符，值为httpconn
};



#endif